package com.yykj.hospital.server.service.impl;

import com.yykj.common.constant.CommonConstant;
import com.yykj.common.enums.HospitalOnlineTypeEnum;
import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import com.yykj.common.util.LocalObjectUtil;
import com.yykj.hospital.client.dto.*;
import com.yykj.hospital.server.converter.HospitalSettingOnlineDTOConverter;
import com.yykj.hospital.server.form.HospitalOnlineSettingEditForm;
import com.yykj.hospital.server.model.entity.*;
import com.yykj.hospital.server.model.repository.*;
import com.yykj.hospital.server.service.HospitalService;
import com.yykj.hospital.server.service.HospitalSettingService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class HospitalSettingServiceImpl implements HospitalSettingService {
    @Override
    public List<HospitalSettingOnlineDTO> listHospitalOnlineSetting(Integer hospitalId) {
        List<HospitalSettingOnline> settingList = onlineSettingRepository.findAllByHospitalId(hospitalId);
        if (settingList == null || settingList.size() == 0) {
            settingList = HospitalSettingOnline.defaultHospitalSettingOnline(hospitalId);
            onlineSettingRepository.saveAll(settingList);
        } else {
            if (settingList.size() != 4) {
                Set<HospitalOnlineTypeEnum> typeEnumSet = new HashSet<>();
                for (HospitalSettingOnline online : settingList) {
                    typeEnumSet.add(online.getType());
                }
                for (HospitalOnlineTypeEnum type : HospitalOnlineTypeEnum.values()) {
                    if (!typeEnumSet.contains(type)) {
                        settingList.add(HospitalSettingOnline.defaultHospitalSettingOnline(hospitalId, type));
                    }
                }
                onlineSettingRepository.saveAll(settingList);
            }
        }

        return HospitalSettingOnlineDTOConverter.convert(settingList);
    }

    @Override
    public HospitalSettingOnlineDTO editHospitalOnlineSetting(HospitalOnlineSettingEditForm form) {
        HospitalSettingOnline setting = onlineSettingRepository.findFirstByHospitalIdAndType(form.getHospitalId(), form.getType());
        if (setting == null) {
            setting = HospitalSettingOnline.defaultHospitalSettingOnline(form.getHospitalId(), form.getType());
        }
        LocalObjectUtil.copyNullValue(form, setting);
        setting.setHospitalId(form.getHospitalId());
        setting = onlineSettingRepository.save(setting);


        // 医院修改了问诊时间，同步修改医生已经配置的时间
        List<DoctorOnlinePriceSetting> priceSettingList = doctorPriceSettingRepository.findAllByHospitalIdAndType(form.getHospitalId(), form.getType());
        for (DoctorOnlinePriceSetting onlinePriceSetting : priceSettingList) {
            onlinePriceSetting.setTime(setting.getTime());
        }
        doctorPriceSettingRepository.saveAll(priceSettingList);

        return HospitalSettingOnlineDTOConverter.convert(setting);
    }

    @Override
    public void initHospitalOnlineSetting(Integer hospitalId) {
        onlineSettingRepository.saveAll(HospitalSettingOnline.defaultHospitalSettingOnline(hospitalId));
    }

    @Override
    public void initHospitalSetting(Integer hospitalId) {

        HospitalSetting setting = HospitalSetting.defaultHospitalSetting(hospitalId);
        settingRepository.save(setting);

        HospitalSettingOnlineOther build = HospitalSettingOnlineOther.defaultHospitalSettingOnlineOther(hospitalId);
        onlineOtherRepository.save(build);

        HospitalSettingAppointment build1 = HospitalSettingAppointment.defaultHospitalSettingAppointment(hospitalId);
        appointmentRepository.save(build1);

        HospitalSettingCheck hospitalSettingCheck = HospitalSettingCheck.defaultHospitalSettingCheck(hospitalId);
        checkRepository.save(hospitalSettingCheck);

    }

    @Override
    public HospitalSettingOnlineOther viewHospitalSettingOnlineOther(Integer hospitalId) {
        return onlineOtherRepository.findById(hospitalId).orElse(HospitalSettingOnlineOther.defaultHospitalSettingOnlineOther(hospitalId));
    }

    @Override
    public HospitalSettingOnlineOther editHospitalSettingOnlineOther(HospitalSettingOnlineOther other) {
        HospitalSettingOnlineOther onlineOther = onlineOtherRepository.findById(other.getHospitalId())
                .orElse(HospitalSettingOnlineOther.defaultHospitalSettingOnlineOther(other.getHospitalId()));
        LocalObjectUtil.copyNullValue(other, onlineOther);
        return onlineOtherRepository.save(onlineOther);
    }

    @Override
    public HospitalSettingCheck viewHospitalCheckSetting(Integer hospitalId) {
        return checkRepository.findById(hospitalId).orElse(HospitalSettingCheck.defaultHospitalSettingCheck(hospitalId));
    }

    @Override
    public HospitalSettingCheck editHospitalCheckSetting(HospitalSettingCheck form) {
        HospitalSettingCheck check = checkRepository.findById(form.getHospitalId()).orElse(HospitalSettingCheck.defaultHospitalSettingCheck(form.getHospitalId()));
        check.setCnt1(form.getCnt1());
        checkRepository.save(check);
        return check;
    }

    @Override
    public HospitalSettingAppointment viewHospitalSettingAppointment(Integer hospitalId) {
        return appointmentRepository.findById(hospitalId).orElse(HospitalSettingAppointment.defaultHospitalSettingAppointment(hospitalId));
    }

    @Override
    public HospitalSettingAppointment editHospitalSettingAppointment(HospitalSettingAppointment form) {
        HospitalSettingAppointment setting = appointmentRepository.findById(form.getHospitalId())
                .orElse(HospitalSettingAppointment.defaultHospitalSettingAppointment(form.getHospitalId()));
        LocalObjectUtil.copyNullValue(form, setting);
        setting = appointmentRepository.save(setting);
        return setting;
    }

    @Override
    public HospitalConfigInfo getHospitalConfigInfo(Integer hospitalId) {
        HospitalConfigInfo info = new HospitalConfigInfo();

        HospitalSettingCheck check = this.viewHospitalCheckSetting(hospitalId);
        HospitalSettingCheckDTO checkDTO = new HospitalSettingCheckDTO();
        BeanUtils.copyProperties(check, checkDTO);
        info.setSettingCheck(checkDTO);

        HospitalSettingAppointment appointment = this.viewHospitalSettingAppointment(hospitalId);
        HospitalSettingAppointmentDTO appointmentDTO = new HospitalSettingAppointmentDTO();
        BeanUtils.copyProperties(appointment, appointmentDTO);
        info.setSettingAppointment(appointmentDTO);

        info.setOnlineSetting(this.listHospitalOnlineSetting(hospitalId));

        HospitalSettingOnlineOther settingOnlineOther = this.viewHospitalSettingOnlineOther(hospitalId);
        HospitalSettingOnlineOtherDTO onlineOtherDTO = new HospitalSettingOnlineOtherDTO();
        BeanUtils.copyProperties(settingOnlineOther, onlineOtherDTO);
        info.setSettingOnlineOther(onlineOtherDTO);

        info.setHospitalSetting(hospitalService.getHospitalSetting(hospitalId));

        return info;
    }

    @Override
    public HospitalSettingAppointDialog viewHospitalSettingAppointDialog(Integer hospitalId) {
        return dialogRepository.findById(hospitalId).orElse(HospitalSettingAppointDialog.defaultHospitalSettingAppointDialog(hospitalId));
    }

    @Override
    public HospitalSettingAppointDialog editHospitalSettingAppointDialog(HospitalSettingAppointDialog dialog) {
        HospitalSettingAppointDialog old = dialogRepository.findById(dialog.getHospitalId()).orElse(HospitalSettingAppointDialog.defaultHospitalSettingAppointDialog(dialog.getHospitalId()));
        LocalObjectUtil.copyNullValue(dialog, old);
        old = dialogRepository.save(old);
        return old;
    }

    @Override
    public DoctorOnlinePriceSetting editDoctorOnlinePriceSetting(DoctorOnlinePriceSetting setting) {
        if (CommonConstant.MAX_PRICE.compareTo(setting.getPrice()) < 0) {
            throw new NormalException(ResultEnums.MAX_PRICE_ERROR);
        }
        if (CommonConstant.MIN_PRICE.compareTo(setting.getPrice()) > 0) {
            throw new NormalException(ResultEnums.MIN_PRICE_ERROR);
        }
        if (setting.getHospitalId() == null || setting.getHospitalId() <= 0) {
            throw new NormalException(ResultEnums.PARAM_ERROR, "医院ID不能为空");
        }
        DoctorOnlinePriceSetting priceSetting = doctorPriceSettingRepository.findByDoctorIdAndType(setting.getDoctorId(), setting.getType());
        if (priceSetting == null) {
            priceSetting = DoctorOnlinePriceSetting.defaultDoctorOnlinePriceSetting(setting.getHospitalId(), setting.getDoctorId(), setting.getType());
        }

        priceSetting.setPrice(setting.getPrice());
        priceSetting = doctorPriceSettingRepository.save(priceSetting);
        return priceSetting;
    }

    @Override
    public List<DoctorOnlinePriceSetting> viewDoctorOnlinePriceSetting(String doctorId) {
        List<DoctorOnlinePriceSetting> list = doctorPriceSettingRepository.findAllByDoctorId(doctorId);

        if (list.size() < 3) {
            HospitalDoctor hospitalDoctor = doctorRepository.findById(doctorId).orElseThrow(() -> new NormalException(ResultEnums.NOT_EXIST));
            List<HospitalSettingOnline> onlineList = onlineSettingRepository.findAllByHospitalId(hospitalDoctor.getHospitalId());
            Map<HospitalOnlineTypeEnum, HospitalSettingOnline> onlineMap = new HashMap<>();
            for (HospitalSettingOnline online : onlineList) {
                onlineMap.put(online.getType(), online);
            }
            Map<HospitalOnlineTypeEnum, DoctorOnlinePriceSetting> map = new HashMap<>();
            for (DoctorOnlinePriceSetting item : list) {
                map.put(item.getType(), item);
            }
            for (HospitalOnlineTypeEnum type : HospitalOnlineTypeEnum.values()) {
                if(HospitalOnlineTypeEnum.xufang.equals(type)){
                    continue;
                }
                if (map.get(type) == null) {
                    DoctorOnlinePriceSetting setting = DoctorOnlinePriceSetting.defaultDoctorOnlinePriceSetting(hospitalDoctor.getHospitalId(), doctorId, type);
                    setting.setHospitalId(hospitalDoctor.getHospitalId());
                    setting.setPrice(onlineMap.get(type).getPrice());
                    setting.setTime(onlineMap.get(type).getTime());
                    list.add(setting);
                }
            }
        }

        return list;
    }


    private HospitalSettingAppointmentRepository appointmentRepository;

    private HospitalSettingOnlineRepository onlineSettingRepository;

    private HospitalSettingRepository settingRepository;

    private HospitalSettingOnlineOtherRepository onlineOtherRepository;

    private HospitalSettingCheckRepository checkRepository;

    private HospitalService hospitalService;

    private HospitalSettingAppointDialogRepository dialogRepository;

    private DoctorOnlinePriceSettingRepository doctorPriceSettingRepository;

    private HospitalDoctorRepository doctorRepository;

    @Autowired
    public void setOnlineSettingRepository(HospitalSettingOnlineRepository onlineSettingRepository) {
        this.onlineSettingRepository = onlineSettingRepository;
    }

    @Autowired
    public void setSettingRepository(HospitalSettingRepository settingRepository) {
        this.settingRepository = settingRepository;
    }

    @Autowired
    public void setOnlineOtherRepository(HospitalSettingOnlineOtherRepository onlineOtherRepository) {
        this.onlineOtherRepository = onlineOtherRepository;
    }

    @Autowired
    public void setAppointmentRepository(HospitalSettingAppointmentRepository appointmentRepository) {
        this.appointmentRepository = appointmentRepository;
    }

    @Autowired
    public void setCheckRepository(HospitalSettingCheckRepository checkRepository) {
        this.checkRepository = checkRepository;
    }

    @Autowired
    public void setHospitalService(HospitalService hospitalService) {
        this.hospitalService = hospitalService;
    }

    @Autowired
    public void setDialogRepository(HospitalSettingAppointDialogRepository dialogRepository) {
        this.dialogRepository = dialogRepository;
    }

    @Autowired
    public void setDoctorPriceSettingRepository(DoctorOnlinePriceSettingRepository doctorPriceSettingRepository) {
        this.doctorPriceSettingRepository = doctorPriceSettingRepository;
    }

    @Autowired
    public void setDoctorRepository(HospitalDoctorRepository doctorRepository) {
        this.doctorRepository = doctorRepository;
    }
}
